using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using EARTHLib;
using System.Diagnostics;
using GEPlugin;
using System.IO;
using System.Xml;


namespace BlimpControlPanel
{
   public partial class googleEarthControl : UserControl
   {
      [DllImport("user32.dll")]
      static extern int SetParent(int hWndChild, int hWndParent);

      [DllImport("user32.dll", CharSet = CharSet.Auto)]
      public extern static bool SetWindowPos(int hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

      [DllImport("user32.dll")]
      private static extern bool ShowWindowAsync(int hWnd, int nCmdShow);


      [DllImport("user32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam);

      [DllImport("user32.dll")]
      private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);


      [DllImport("user32", CharSet = CharSet.Auto)]
      public extern static IntPtr GetParent(IntPtr hWnd);
      [DllImport("user32", CharSet = CharSet.Auto)]
      public extern static bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

      [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
      public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);

      public const int GW_CHILD      = 5;
      public const int GW_HWNDNEXT   = 2;
      private IntPtr GEHrender       = (IntPtr)5;
      private IntPtr GEParentHrender = (IntPtr)5;

      readonly IntPtr HWND_TOP    = new IntPtr(0);
      readonly IntPtr HWND_BOTTOM = new IntPtr(1);

      static readonly UInt32 SWP_NOSIZE     = 1; 
      static readonly UInt32 SWP_SHOWWINDOW = 64;
      static readonly UInt32 SWP_HIDEWINDOW = 128; 

      static readonly Int32 WM_QUIT      = 0x0012;
      private const int WM_COMMAND       = 0x0112;
      private const int WM_QT_PAINT      = 0xC2DC;
      private const int WM_PAINT         = 0x000F;
      private const int WM_SIZE          = 0x0005;
      private const int SWP_FRAMECHANGED = 0x0020;

      private ApplicationGEClass m_geApp;
      

      private IntPtr m_OriginalParent_hWnd;
      private int m_OriginalParentWidth;
      private int m_OriginalParentHeight;

      public googleEarthControl(ApplicationGEClass ge, IntPtr geParentWnd, int width, int height)
      {
         m_geApp = ge;
         m_OriginalParent_hWnd  = geParentWnd;
         m_OriginalParentWidth  = width;
         m_OriginalParentHeight = height;

         InitializeComponent();

         try
         {
            this.Height       = height;
            this.Width        = width;
            this.pnlGE.Height = height;
            this.pnlGE.Width  = width;

            GEHrender = (IntPtr)ge.GetRenderHwnd();
            GEParentHrender = GetParent(GEHrender);
            SetupGoogleEarthWindow();
            ShowWindowAsync(m_geApp.GetMainHwnd(), 0);
         }
         catch(Exception ex)
         {
             MessageBox.Show(ex.Message);
         }
      }

      private void SetupGoogleEarthWindow()
      {
          ShowWindowAsync(m_geApp.GetMainHwnd(), 0);
          MoveWindow(GEHrender, 0, 0, this.pnlGE.Width, this.pnlGE.Height, true);

          // Set to the new parent. pnlGE is a panel control in MyDialog - not
          // to be confused with the pnlGE control that is in the calling form.
          SetParent(m_geApp.GetRenderHwnd(), pnlGE.Handle.ToInt32());

          ResizeGoogleControl();
          // Set the window position.
//          SetWindowPos(m_geApp.GetRenderHwnd(), HWND_TOP, 0, 0, pnlGE.Width, pnlGE.Height, SWP_SHOWWINDOW);
//          SetWindowPos(m_geApp.GetRenderHwnd(), HWND_BOTTOM, this.pnlGE.Location.X, this.pnlGE.Location.Y, this.Width, this.Height, SWP_SHOWWINDOW + SWP_NOSIZE);
//          SetWindowPos(m_geApp.GetMainHwnd(), HWND_BOTTOM, this.pnlGE.Location.X, this.pnlGE.Location.Y, this.Width, this.Height, SWP_HIDEWINDOW + SWP_NOSIZE);
      }

      private void ResizeGoogleControl()
      {
          SendMessage(m_geApp.GetMainHwnd(), WM_COMMAND, WM_PAINT, 0);
          PostMessage(m_geApp.GetMainHwnd(), WM_QT_PAINT, 0, 0);

          SetWindowPos(m_geApp.GetMainHwnd(),
                       HWND_TOP,
                       0,
                       0,
                       (int)this.Width,
                       (int)this.Height,
                       SWP_FRAMECHANGED);

          SendMessage(m_geApp.GetRenderHwnd(), WM_COMMAND, WM_SIZE, 0);
      }

      /// <summary>
      /// This function is used to properly resize the application window to the new application height
      /// and width.
      /// </summary>
      /// <param name="e"></param>
      protected override void OnSizeChanged(EventArgs e)
      {
         base.OnSizeChanged(e);
         Debug.WriteLine("Width: " + this.pnlGE.Width.ToString() + " Height: " + this.pnlGE.Height.ToString());
      }

      /// <summary>
      /// Moves the camera view to the given longitude, latitude, and altitude.  This will
      /// also create a placemark at that point.
      /// </summary>
      /// <param name="longitude">Current logitude of the point.</param>
      /// <param name="latitude">Current latitude of the point.</param>
      /// <param name="altitude">Current altitude of the point.</param>
      public void GotoPoint(double longitude, double latitude, double altitude)
      {
          xmlParsing xml = new xmlParsing();
          xml.saveKMLNetworkLinkCoordinates(latitude, longitude, altitude);

          m_geApp.SetCameraParams(latitude, longitude, 200, AltitudeModeGE.AbsoluteAltitudeGE, 200, 0, 0, 10);
      }

      public void TestGetFeature()
      {
          string networkLinkFilename = @"c:\testNWL.kml";

          try
          {
              string test = "";

              if (File.Exists(networkLinkFilename))
              {
                  StreamReader sw = new StreamReader(new FileStream(networkLinkFilename, FileMode.Open));

                  while (!sw.EndOfStream)
                      test += sw.ReadLine();

                  sw.Close();
              }

              m_geApp.OpenKmlFile(networkLinkFilename, 0);
          }
          catch (Exception ex)
          {
              Debug.WriteLine("Error Loading KML Data: " + ex.Message);
          }

      }

      public void UpdateCoordinates()
      {
          
      }

      /// <summary>
      /// Called when closing the application so that Google Earth will be shutdown.
      /// </summary>
      public void googleEarthControlClose()
      {
         try
         {
            // Quit the Google Earth process.
            PostMessage(m_geApp.GetMainHwnd(), WM_QUIT, 0, 0);
         }
         catch
         {
         }
      }
   }
}
